package com.lgCore.clientInvok;

import com.lgCore.client.factory.CommonRpcClientFactory;
import com.lgCore.common.IpDataEntity;
import com.lgCore.common.RpcException;
import com.lgCore.message.CommonRpcRequest;
import com.lgCore.netty.client.NettyClientBootstrap;
import com.lgCore.netty.message.AskMsg;
import com.lgCore.netty.message.AskParams;
import com.lgCore.netty.message.Constants;
import com.lgCore.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.UUID;

/**
 *
 * rpc客户端调用处理中心
 * ligang 2020/05/07
 */
@Component
public class RpcFactory<T> implements InvocationHandler {


    Logger logger = LoggerFactory.getLogger(this.getClass());

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
            //查询zk地址
            String className = method.getDeclaringClass().getName();
            String zkPath=null;
//            zkPath = CommonRpcClientFactory.getiCommonRpcClientService().getServerDataByZk(className);
//            检验ip是否能ping通，不然循环取5次
            for (int i = 0; i < 5; i++) {
                zkPath = CommonRpcClientFactory.getiCommonRpcClientService().getServerDataByZk(className);
                if(StringUtils.isNullOrEmpty(zkPath)){
                    //可能由于zk客户端还没打开，所以需要等待
                    Thread.sleep(300);
                    continue;
                }
                //IP是否能ping通
                String ip = zkPath.split(":")[0];
                boolean pingIp = IpDataEntity.isPing(ip);
                if (pingIp) {
                    break;
                }
            }
            if (StringUtils.isNullOrEmpty(zkPath)) {
                throw new RpcException("没有可以连接的IP");
            }

//            zkPath="192.168.20.149:40549";
            //查询netty服务 bootStrap
            NettyClientBootstrap nettyClientBootstrap = CommonRpcClientFactory.getiCommonRpcClientService().getServerBootStrap(zkPath);
//        Class<?>[] paramTypes = new Class[]{String.class};
            //执行业务方法
            CommonRpcRequest commonRpcRequest = new CommonRpcRequest();
            commonRpcRequest.setServiceName(className);
            commonRpcRequest.setRequestId(UUID.randomUUID().toString());
            commonRpcRequest.setMethodName(method.getName());
//        commonRpcRequest.setArgTypes(paramTypes);
            commonRpcRequest.setRequestObjects(args);
            AskMsg askMsg = new AskMsg();
//            askMsg.setClientId(Constants.getClientId());
            AskParams askParams = new AskParams();
            askParams.setCommonRpcRequest(commonRpcRequest);
            askMsg.setParams(askParams);
            askMsg.setBusinessId(UUID.randomUUID().toString());
            Object object = CommonRpcClientFactory.getiCommonRpcClientService().executeSendRequest(nettyClientBootstrap, askMsg);
//            Date date= new Date();
//            for(int i=0;i<100000;i++){
//                CommonRpcClientFactory.getiCommonRpcClientService().executeSendRequest(nettyClientBootstrap, askMsg);
//            }
//            logger.info("时间is"+(new Date().getTime()-date.getTime()));


            return object;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RpcException("rpc 调用失败");
        }
    }


}
